﻿/*
 * pb_main.cpp
 *
 *  Created on: 2017年10月31日
 *      Author: work
 */

#include <dm/os/protocol/protocolcontrolor.hpp>
#include <dm/os/ascom/tcpclientdevice.hpp>
#include <boost/program_options.hpp>
#include <boost/bind.hpp>
#include <dm/env/env.hpp>
#include <iostream>

#include <dm/os/sys/taskagent.hpp>
#include <dm/os/com/timer.hpp>

#include "protocol_tcp.hpp"

using namespace std;
using namespace boost::program_options;

int main( int argc,char* argv[] ){
	options_description desc("【DM2016帮助文档】\n 通用modbus主站程序。\n\t基于DM2016系统构建\n支持以下选项");

	options_description generic("一般选项");
	generic.add_options()
			("help,h","显示本帮助信息")
			("version,v","显示版本及编译信息")
			("test","测试模式")
			("debug","详细调试模式")
			;
	desc.add(generic);

	options_description opt_pb("通信参数");
	opt_pb.add_options()
			("dev",value<string>(),"设备名")
			("type",value<string>()->default_value("tcp"),"规约类型：tcp modbus-tcp, rtu modbus-rtu")
			("cfg",value<string>()->default_value("modbus.xml"),"规约配置文件")
			("interval,i",value<int>()->default_value(200),"设置刷新周期：毫秒")
			("slaver",value<int>()->default_value(1),"从站地址")
			("ip",value<string>()->default_value("192.168.7.101"),"ip地址")
			("port",value<short>()->default_value(502),"端口号");

	desc.add(opt_pb);

	variables_map vm;
	try{
		store(parse_command_line(argc,argv,desc),vm);
		notify(vm);
	}catch( std::exception& ex ){
		cout << ex.what()<<endl;
		return 1;
	}

	if( vm.count("help") ){
		cout <<desc<<endl;
		return 1;
	}

	if( vm.count("version") ){
		cout <<"V1.0 构建于 "<<__DATE__<<endl;
		return 1;
	}


	dm::os::sys::CTaskAgent* taskAgent = NULL;
	if( !vm.count("test") )
		taskAgent = new dm::os::sys::CTaskAgent(argc,argv);

	dm::os::com::ios_t ios;

	dm::os::com::CTcpClientAddr tcpClientAddr;

	tcpClientAddr.setServerHost(vm["ip"].as<string>().c_str());
	tcpClientAddr.setServerPort(vm["port"].as<short>());

	dm::os::ascom::CTcpClientDevice* tcpClientDevice = new dm::os::ascom::CTcpClientDevice(ios);

	if( !tcpClientDevice->setAddress(tcpClientAddr) ){
		cout <<"设置地址失败:"<<tcpClientAddr.toString()<<endl;
		return 0;
	}

	dm::os::protocol::CProtocolControlor* controlor = new dm::os::protocol::CProtocolControlor(ios);
	string cfg = dm::env::getCfgFilePath(vm["cfg"].as<string>().c_str());
	dm::protocol::CModbusMap modbusMap;
	if( modbusMap.init(cfg.c_str())==false ){
		cout <<"配置文件加载失败"<<cfg<<endl;
		return 1;
	}

	CProtocolTcp* protocol = new CProtocolTcp(&modbusMap);
	protocol->setDebug(vm.count("debug"));
	protocol->setUnitFlag(vm["slaver"].as<int>());

	protocol->setRefreshInterval(vm["interval"].as<int>());

	if( !protocol->setDev(vm["dev"].as<string>().c_str()) ){
		cout <<"设置设备失败:"<<vm["dev"].as<string>()<<endl;
		return 1;
	}

	controlor->setProtocol(protocol);
	controlor->setDevice(tcpClientDevice);
	controlor->setAutoConnect();
	controlor->openDevice();

	if( !taskAgent ){
		ios.run();
	}else{
		dm::os::com::CTimer timer(ios);
		timer.start_seconds(true,10);
		while( taskAgent->runOnce() ){
			ios.run_one();
			if( controlor->isExiting() )
				break;
		}

		delete taskAgent;
	}

	return 0;
}
